#ifndef DDC_COMPONENT_H_INCLUDED
#define DDC_COMPONENT_H_INCLUDED

#include "SDL.h"

#include "ddc_internal.h"
#include "ddc_obj.h"
#include "ddc_sprite.h"

const int DDC_COMPONENT_BASE = 1;
const int DDC_COMPONENT_COLLIDER2D = 2;
const int DDC_COMPONENT_SPRITE2D = 3;
const int DDC_COMPONENT_UISPRITE2D = 3;

class DDC_BoxCollider2D: public DDC_Component {
public:
    DDC_Vector2 center;
    DDC_Tuple2 size;

    DDC_BoxCollider2D()
        :center(), size() {}

    virtual int GetComponentID() {
        return DDC_COMPONENT_COLLIDER2D;
    }

    void Init(DDC_Vector2 center, DDC_Tuple2 size) {
        this->center = center;
        this->size = size;
    }

    DDC_Vector2 GetCenterPosOfWorld();
    bool Hit(DDC_BoxCollider2D &c2d);
};

class DDC_Sprite2D: public DDC_Component {
    DDC_SpriteRenderer *renderer = nullptr;
    DDC_SpriteFlip::DDC_SpriteFlipEnum flipMode = DDC_SpriteFlip::FLIP_NONE;

protected:
    bool __FixedSprite = false;

public:
    bool keepTextureScale = 0;

    virtual void Update();

    virtual int GetComponentID() {
        return DDC_COMPONENT_SPRITE2D;
    }

    template <typename T>
    T *UseSpriteRenderer() {
        if (renderer != nullptr)
            delete renderer;

        renderer = new T;
        renderer->__SetRenderer(__gDodocoMainRenderer);
        renderer->__FixedOnScreen = __FixedSprite;
        return (T *)renderer;
    }

    template <typename T>
    T *GetSpriteRender() {
        return dynamic_cast<T*>(renderer);
    }

    DDC_Sprite2D *SetSpriteFlipMode(DDC_SpriteFlip::DDC_SpriteFlipEnum flipMode) {
        this->flipMode = flipMode;
        return this;
    }

    DDC_Sprite2D *SetKeepTextureScale(bool val) {
        keepTextureScale = val;
        return this;
    }
};

class DDC_UISprite2D: public DDC_Sprite2D {
public:
    DDC_UISprite2D(): DDC_Sprite2D() {
        __FixedSprite = true;
    }

    virtual int GetComponentID() {
        return DDC_COMPONENT_UISPRITE2D;
    }
};

#endif // DDC_COMPONENT_H_INCLUDED
